import os
import math

try:
    import wx
except ModuleNotFoundError:
    os.system("pip install wxPython")
    import wx

import MainFrame

# This is my first time trying wxPython
# I have to say that Qt is better ... (somehow ugly)

class MyFrame(MainFrame.MainFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.theta = 0
        self.sintheta = 0
    
    def getGrid(self) -> list:
        ret = []
        for i in range(self.m_gridData.GetNumberRows()):
            cur = []
            for j in range(self.m_gridData.GetNumberCols()):
                cur.append(self.m_gridData.GetCellValue(i, j))
            ret.append(cur)
        return ret

    def setGrid(self, data:list):
        for i in range(self.m_gridData.GetNumberRows()):
            for j in range(self.m_gridData.GetNumberCols()):
                self.m_gridData.SetCellValue(i, j, data[i][j])

    def m_menuItemExportOnMenuSelection(self, event):
        dlg = wx.FileDialog(self, "Select a filename for save...", 
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            with open(dlg.GetPath(), "w") as ofile:
                ofile.write(str(self.getGrid()))
        else:
            wx.MessageBox("File Not Save!", "Warning")
        return super().m_menuItemExportOnMenuSelection(event)

    def m_menuItemImportOnMenuSelection(self, event):
        dlg = wx.FileDialog(self, "Open data file you saved...", style=wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            with open(dlg.GetPath(), "r") as ifile:
                self.setGrid(eval(ifile.read()))
        else:
            wx.MessageBox("File Not Open!", "Warning")
        return super().m_menuItemImportOnMenuSelection(event)

    def m_buttonCalculateOnButtonClick(self, event):
        tab = self.getGrid()
        data = []

        try:
            n, m = len(tab), len(tab[0])
            for j in range(m):
                avg = 0
                for i in range(n):
                    avg += eval(tab[i][j] + "/60")
                avg /= n
                data.append(avg)
            self.theta = (abs(data[0] - data[2]) + abs(data[1] - data[3])) / 4
            self.sintheta = math.sin(math.radians(self.theta))

            deg = math.floor(self.theta)
            mini = (self.theta - deg) * 60
            sec = round((mini - math.floor(mini)) * 60)
            mini = math.floor(mini)

            theta_str = str(deg) + '°' + str(mini) + '′' + str(sec) + '″'
            sin_str = "%.5f" % self.sintheta
            self.m_textCtrlTheta.SetValue(theta_str)
            self.m_textCtrlSin.SetValue(sin_str)
        except:
            wx.MessageBox("Data Format Incorrect or Unable to Calculate", "Error")

        return super().m_buttonCalculateOnButtonClick(event)

    def m_textCtrlDOnTextEnter(self, event):
        self.m_textCtrlLambda.SetValue("%.1f" % 
            (float(self.m_textCtrlD.GetValue()) * self.sintheta * 1000 / 2))
        return super().m_textCtrlDOnTextEnter(event)

    def m_textCtrlLambdaOnTextEnter(self, event):
        if self.sintheta:
            self.m_textCtrlD.SetValue("%.3f" % (2 * float(self.m_textCtrlLambda.GetValue()) / 
                self.sintheta / 1000))
            
        return super().m_textCtrlLambdaOnTextEnter(event)

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame(None)
    frame.Show(True)
    app.MainLoop()